package es.qb.deportivos.il.dal.impl;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.orm.jpa.JpaCallback;

import es.qb.deportivos.exception.GeneralDAOException;
import es.qb.deportivos.il.dal.interfaces.JugadorDAO;
import es.qb.deportivos.il.domain.Jugador;
import es.qb.deportivos.il.domain.JugadoresEquipo;
import es.qb.deportivos.il.domain.Users;
import es.qb.deportivos.util.Utilities;

public class JugadorDAOImpl extends GeneralDAOImpl<Jugador> implements JugadorDAO {

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Long calculaPJ(Jugador jugador) throws GeneralDAOException {

		Long lPJ = 0L;

		try {

			CriteriaBuilder criteriaBuilder = getJpaTemplate().getEntityManager().getCriteriaBuilder();
			CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();

			Root<JugadoresEquipo> from = criteriaQuery.from(JugadoresEquipo.class);

			Expression countExpression = criteriaBuilder.count((Expression) from.get("id"));
			CriteriaQuery<Object> select = criteriaQuery.select(countExpression);

			List<Predicate> lstPredicate = new ArrayList<Predicate>();

			// Jugador.
			Predicate predicateJugador = null;

			predicateJugador = criteriaBuilder.equal(from.get("jugador").get("id"), jugador.getId());
			lstPredicate.add(predicateJugador);

			criteriaQuery.where(criteriaBuilder.and(Utilities.crearPredicateVariable(lstPredicate)));

			TypedQuery<Object> typedQuery = getJpaTemplate().getEntityManager().createQuery(select);
			lPJ = (Long) typedQuery.getSingleResult();

			return lPJ;
		} catch (PersistenceException e) {
			throw new GeneralDAOException("IL-DAL-BUSCARPUNTOS", "Se ha producido un error al buscar los puntos." + e);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Long calculaPG(Jugador jugador) throws GeneralDAOException {

		Long lPG = 0L;

		// TODO

		return lPG;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Long calculaPE(Jugador jugador) throws GeneralDAOException {

		Long lPE = 0L;

		// TODO

		return lPE;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Long calculaPP(Jugador jugador) throws GeneralDAOException {

		Long lPP = 0L;

		// TODO

		return lPP;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Long calculaGOL(Jugador jugador) throws GeneralDAOException {

		Long lGOL = 0L;

		try {

			CriteriaBuilder criteriaBuilder = getJpaTemplate().getEntityManager().getCriteriaBuilder();
			CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();

			Root<JugadoresEquipo> from = criteriaQuery.from(JugadoresEquipo.class);

			Expression countExpression = criteriaBuilder.sum((Expression) from.get("goles"));
			CriteriaQuery<Object> select = criteriaQuery.select(countExpression);

			List<Predicate> lstPredicate = new ArrayList<Predicate>();

			// Jugador.
			Predicate predicateJugador = null;

			predicateJugador = criteriaBuilder.equal(from.get("jugador").get("id"), jugador.getId());
			lstPredicate.add(predicateJugador);

			criteriaQuery.where(criteriaBuilder.and(Utilities.crearPredicateVariable(lstPredicate)));

			TypedQuery<Object> typedQuery = getJpaTemplate().getEntityManager().createQuery(select);
			lGOL = (Long) typedQuery.getSingleResult();

			return lGOL;
		} catch (PersistenceException e) {
			throw new GeneralDAOException("IL-DAL-BUSCARPUNTOS", "Se ha producido un error al buscar los puntos." + e);
		}
	}

	public Users cargarUsuario(String username) {

		String consulta = "select * from users u where u.username = '" + username + "'";

		List<?> lista = findUsingSql(consulta);

		Users usuario = new Users();
		for (Object object : lista) {
			Object o[] = (Object[]) object;

			if (o[0] != null) {
				usuario.setNombreUsuario(o[0].toString());
			}

			if (o[1] != null) {
				usuario.setPassword(o[1].toString());
			}

		}

		return usuario;

	}

	public List<?> findUsingSql(final String sql) {
		return getJpaTemplate().executeFind(new JpaCallback<Object>() {
			public Object doInJpa(EntityManager entityManager) throws PersistenceException {
				return entityManager.createNativeQuery(sql).getResultList();
			}
		});
	}

	public Users guardarCambioPassword(Users usuarioNuevo) {

		String consulta = "UPDATE users s SET s.password = '" + usuarioNuevo.getPassword() + "' where s.username ='"
				+ usuarioNuevo.getNombreUsuario() + "'";

		Query createNativeQuery = getJpaTemplate().getEntityManager().createNativeQuery(consulta);
		createNativeQuery.executeUpdate();

		return usuarioNuevo;
	}

}
